// let globalData1 = getApp()
/**一个很奇怪的现象
 * 
 * 1 任何函数都是可以使用当前页面定义的参数的，即使这个函数被暴露出去
 *   在别的页面被引用
 * 2 如果你在页面定义let globalData1 = getApp()
 *   那么globalData1 在函数中可以被使用
 *   如果被app.js 引用 这个globalData1 就是underfined
 * 3 如果你直接在函数中调用 getApp() ,那么是可以获取到值的。
 * 
 * 
 * **/ 



/**
 * 1 js 文件里面的数据外部无法访问
 * 2 export 暴露出去之后才可以访问
 * 3 爆漏出去的方法内部可以直接访问当前js 文件中变量
 * 4 即使文件中引入当前js 文件中的函数，函数内部依然没有办法使用引入文件中的
 *   变量 和 this 关键字。
 *   这个函数只能使用当前页面的参数，或者在函数的括号里面把另外一个页面的参数传递进来。
 *  
 * **/ 
import {getUnReadMsg,readMessage} from './chat.js';
import {hostIp,hostPort} from '../../api/api.js';
import {formatTime}  from '../utils/util.js';
let userSocket;//socket 对象
let heartFlag;//重连定时器的标志，如果超时没有回复，那么会重连
//调用这个方法去建立一个聊天链接，然后添加一些监听。
export function openSocket(globalData){
  // let globalData = that.globalData;
  console.log(globalData,"test")
  //链接-------------------------
  //ws:9200/user/{openid}
  let openid = wx.getStorageSync('loginInfo').phone; 
  console.log(openid,"手机号码================")
  // 有可能会出现反复重连的情况
  // 所以链接之前要先判断 全局标志是断开的才会重连
  if(globalData.userSocketStatus == "closed"){
    console.log("准备链接-----------",hostIp,hostPort);
    userSocket =  wx.connectSocket({
      url: "ws://"+hostIp+":"+hostPort+`/user/${openid}`, 
    })
    console.log(userSocket,"------------")
  }else{
    console.log("%c 重连失败，因为全局标志为connected ，意思是链接已经存在，只有userSocketStatus == “closed” 的时候才会重连","color:yellow;font-size:20px;")
  }



  //监听链接事件
  userSocket.onOpen(res=>{
      console.log(res,"用户已经链接聊天服务器");
      console.log("%c服务器已经链接...","color:yellow;font-size:20px;")
      globalData.userSocketStatus = 'connected';
      //链接之后发送心跳包
      sendHeart();
  })
 
  
  // 监听断开事件
  userSocket.onClose(res=>{
       console.log(res,"用户已经断开聊天服务器");
       console.log("%c用户已经断开聊天服务器...","color:yellow;font-size:20px;")
       globalData.userSocketStatus = 'closed';
      //  openSocket(globalData);
      connectAgaiin()
  })


  //监听链接出错
  userSocket.onError(res=>{
       console.log(res,"用户链接出错");
       console.log("%c用户链接出错...","color:yellow;font-size:20px;")
       
  })

  //监听服务器推送的消息------------------

  /**
   * 0 
   *   1）播放声音
   *   2）如果是从
   * 
   * 
   * 接收消息的逻辑
   * 1 在和发送消息的人聊天
   *   1）调用chat 页面的方法渲染页面
   * 2 在聊天页面但是不是和发送该消息的人聊天
   *   2）刷新tabbar
   * 3 在列表页面
   *   1）刷新 列表未读消息数，
   *   2）刷新tabbar 未读消息数
   * 4 在其他页面
   *   1）弹窗
   *   2）刷新tabbar未读消息数
   * 
   * 
   * 
  //  * --------已读消息处理--------------
   *  1 如果是在当前的页面，每次接收到一条消息都要标志为已读
      2 每次进入页面的时候都要把当前的聊天对象的信息标志为已读
      3 每次退出聊天页面的时候都要更新tabbar
   *  

   ------------tabbar消息的处理-----------------------------
     只要是在聊天页面就不需要处理tabbar和未读消息。
   * 
   * **/ 
  userSocket.onMessage(res=>{
       let msg = JSON.parse(res.data);
       let  date=new Date();
       date = formatTime(date);
      //  date=date.toLocaleString('chinese', { hour12: false });
       console.log(date,"获取到时间----------------");

      //判断是平台发送来的消息还是商家还是心跳
      if(msg.type&&msg.type == "heart"){
         console.log("%c 【接收到心跳包】：","color:yellow; font-size:20px;",res); 
         //清除定时器,不需要重连
         clearTimeout(heartFlag); 
         //接收到消息发送   
         setTimeout(() => {
             sendHeart();
         },10000);
         return;
      }else if(msg.initiator&&msg.initiator == "p"){
          //平台消息
          //播放音乐
          playMusic();
     
        //震动
        wx.vibrateShort();
        console.log("%c 【接收到平台消息】：","color:orange; font-size:20px;",res,msg);
        // console.log(msg,"接收到的消息-------------------------");
        //推送过来的消息是实时消息，所以可以不使用服务端的时间
        // 可以自己new 一个时间出来
        //商家消息
        //解析数据格式 
          let msg1={
              chatTime:date,
              content:msg.content,
              initiator:'m',
              mname:msg.pName,
              merchantId:msg.platformId,
              mHeadImage:msg.pHeadImage
          }
          //除了接收到聊天的人的信息以外，所有的情况都需要改变brgda
          //console.log("解析过的数据",msg1);
          //根据路由，判断当前用户所处的页面
          let pages = getCurrentPages();
          let currentPage = pages[pages.length-1];
          console.log(currentPage);
          if(currentPage.route == "pages/platForm/chat"){
              // wx.showToast({
              //   title: '在商家客服页面',
              // })
              console.log("在平台客服页面=================")
              //在聊天页面
              //如果是正在和发送消息的人聊天，渲染页面
              //如果是和另外的人聊天，弹出提示
              currentPage.receivedMsg(msg1);
              
          }else if(currentPage.route == "pages/chatList/chatList"){
            //在列表页面
            console.log("在列表页面");
            // 1 弹出提示
            // 2 调用list 页面的方法
            // 重新调用getunreadmsg 方法
            currentPage.getListW();
            // 不需要重新getlist
            setBadge();
        }else{
            //在其他页面
            console.log("在其他页面")
            //1 更改标志
            setBadge();
            //2 弹出提示框
            showMsg(msg1)

        }

          
          
          
          
          // else{
          //     //在其他页面
          //     console.log("在其他页面==============================")
          //     //1 更改标志
          //     setBadge();
          //     //2 弹出提示框
          //     showMsg(msg1)
          //     //3 更改跟人中心客服列表的未读数量
          //     // currentPage.setDotNum();

          // }
           
      }else{
             //播放音乐
              playMusic();
              //震动
              wx.vibrateShort();
              console.log("%c 【用户接收到商家消息】：","color:yellow; font-size:20px;",res,msg);
              // console.log(msg,"接收到的消息-------------------------");
              //推送过来的消息是实时消息，所以可以不使用服务端的时间
              // 可以自己new 一个时间出来





            //商家消息
            //解析数据格式 
            let msg1={
                chatTime:date,
                content:msg.content,
                initiator:msg.initiator,
                mname:msg.mName,
                merchantId:msg.merchantId
            }
            //除了接收到聊天的人的信息以外，所有的情况都需要改变brgda
            // console.log("解析过的数据",msg1);
            //根据路由，判断当前用户所处的页面
            let pages = getCurrentPages();
            let currentPage = pages[pages.length-1];
            console.log(currentPage);
            if(currentPage.route == "pages/chat/chat"){
                //在聊天页面
                //如果是正在和发送消息的人聊天，渲染页面
                //如果是和另外的人聊天，弹出提示
                currentPage.receivedMsg(msg1);
                
            }else if(currentPage.route == "pages/chatList/chatList"){
                //在列表页面
                console.log("在列表页面");
                // 1 弹出提示
                // 2 调用list 页面的方法
                // 重新调用getunreadmsg 方法
                currentPage.getListW();
                // 不需要重新getlist
                setBadge();
            }else{
                //在其他页面
                console.log("在其他页面")
                //1 更改标志
                setBadge();
                //2 弹出提示框
                showMsg(msg1)

            }

      }
     
     
  })
 }//----opensocket 方法结束

  


 // 设置tabbar 未读消息数量
//  export function pSetBadge(){
//   //获取未读消息的个数
//   getUnReadMsg().then(res=>{
//      console.log(res,"获取到未读消息")
//      let uReadMsg = res.data.data;
//      if(uReadMsg != ""){
//         let num = uReadMsg['platform'];
//         wx.setTabBarBadge({
//           index:4,
//           text:num.toString()
//         })
//      }else{

//           console.log("获取到未读消息的数量--------------")
//           wx.removeTabBarBadge({
//             index:4,
//           })
//      }
//   })
// }


 

// 设置tabbar 未读消息数量
 export function setBadge(){
    //获取未读消息的个数
    getUnReadMsg().then(res=>{
       console.log(res,"获取到未读消息")
       let uReadMsg = res.data.data;
       let num = 0;
       if(uReadMsg != ""){
          for(let key in uReadMsg){
              let value = Number(uReadMsg[key])
              num+=value;
          }

          if(num != 0){
            wx.setTabBarBadge({
              index:2,
              text:num.toString()
            })
          }else{
              wx.removeTabBarBadge({
                index:2,
              })
          }
       }else{
            wx.removeTabBarBadge({
              index:2,
            })
       }

      

    })
 }


// 弹出消息提示框
 function showMsg(msg){
  let content = JSON.parse(msg.content);
  console.log(content,"content");
  if(content.type == "text"){
      wx.showToast({
        title:`${msg.mname}：【消息】`,   
        image:"../../images1/timg.png",
        duration:3000
      })

  }else{
      //图片
      wx.showToast({
        title:`${msg.mname}：【图片】`,  
        image:"../../images1/timg.png",
        duration:3000
      })

  }
 }

//播放音乐
function playMusic(){
  const innerAudioContext = wx.createInnerAudioContext()
  innerAudioContext.autoplay = true
  innerAudioContext.src = 'pages/utils/music/recived.mp3'
 
}
   
//主动断开链接的方法
export function closeSocket(){
   if(globalData.userSocketStatus === 'connected'){
     wx.closeSocket({
       success:() => {
          globalData.userSocketStatus = 'closed';
          console.log("链接已经关闭....")
          console.log("%c链接已经关闭.....","color:yellow;font-size:20px;")
       }
     })
   }else{
        console.log("链接不存在，之前已经断开了");
        console.log("%c链接不存在，之前已经断开了","color:yellow;font-size:20px;")
   }
}




/**
 * 
data	string/ArrayBuffer		是	需要发送的内容
success	function		否	接口调用成功的回调函数
fail	function		否	接口调用失败的回调函数
complete	function		否	接口调用结束的回调函数（调用成功、失败都会执行）
 * 
 * **/ 
   
//发送消息函数
export function sendMsg(msg){
   //console.log(getApp().globalData,"-------------")
   if (getApp().globalData.userSocketStatus === 'connected') {
       //自定义的发给后台识别的参数 ，我这里发送的是name
       userSocket.send({
          data:JSON.stringify(msg)  
       },res=>{
          console.log("========================消息发送成功",res)
       })
   }else{
      //重新链接
       console.log("%c已经断开链接","color:yellow;")
   }
}

/**
   心跳思路：
   1 链接成功回调中发送一个心跳包
   2 何止定时器，如果超时未清除，那么重新连接
   3 接收到消息清除定时器，
   4 定时器10s 后再次调用 放心跳消息 
   5 递归循环，永不停歇
   

   注意：接收到消息之后才会发送下一个消息
 *      重连之后也会自动调用sendheart
 * 
 * 
 * **/ 

function sendHeart(){
    
    // 2 发送心跳
     let msg= {
         type:"heart", 
         msg:new Date().getTime()
     }
    //发送给服务端 
    // 发送心跳包的前提是没有触发前端的断开和错误事件，send 方法可以正常使用。
    // 如果已经断开了，那么直接发送不了信息，会触发重连机制
  if (getApp().globalData.userSocketStatus === 'connected') {
      //自定义的发给后台识别的参数 ，我这里发送的是name
      userSocket.send({
         data:JSON.stringify(msg)  
      })
      console.log("%c 【心跳包已经发送】.....","color:yellow;");
      heartFlag = setTimeout(() => {
          console.log("%c心跳超时....正在重新连接","color:yellow;")
          // 超时说明链接断开
          getApp().globalData.userSocketStatus = "closed";
          connectAgaiin()
      },5000);

  }else{
     //重新链接
      console.log("%c心跳检测已经断开....正在重新连接","color:yellow;");
      connectAgaiin();
  }

}



/**
 *      重连机制思路
 * 1 opensocket 
 *   1.1链接成功
 *     1.1.1 发送心跳
 *          1）发送成功，接收到心跳
 *             继续发送心跳，递归循环
 *          2）超时未接收到心跳
 *             -->调用openSocket 从头再来
 *     
 *             
 *   1.2连接失败 --> 触发错误回调 -->调用connetAgain-->10s 后调用openSocket
 *      1.2.1  链接成功..回到1.1.1
 *      1.2.2  链接失败  回到 1.2
 * 
 * ***/ 


function connectAgaiin(){
     console.log("%c 调用重连方法","color:yellow;")
     setTimeout(() => {
         openSocket(getApp().globalData)
     },5000);
}






